<?php
class FS{

  public static function glob($path, $pattern = '*', $flags = null, $depth = 0) {
    /*
     * Parametros:
     * $path   - path of folder to search
     * $pattern- glob pattern
     * $flags  - glob flags
     * $depth  - 0 for current folder only, 1 to descend 1 folder down, and so on. -1 for no limit.
     * 
     */

    /*
     * Ejemplo:
     *
     * print_r(FS::glob('{..,../*}','*.ar', GLOB_BRACE)); // --> busca todo lo que termine en .ar
     *                                                         // en .. y en ../* (subdirs de 1er nivel)
     *
     * Array
     * (
     *     [0] => ..\envioftp_df06.com.ar
     *     [1] => ..\estatificador.df06.com.ar
     *     [2] => ..\robots\buscadormulticanal.com.ar
     *     [3] => ..\robots\df02.com.ar
     *     [4] => ..\robots\televisiononline.com.ar
     * )
     *
     * ======================
     *
     * Otro ejemplo:
     *
     * print_r(FS::glob('{..,../*.ar}','*.php', GLOB_BRACE)); // --> busca todos los .php
     *                                                             // en .. y en ../*.ar
     *                                                             //            (subdirs de 1er nivel que terminen en .ar)
     *
     * Array
     * (
     *     [0] => ..\cambiaOcesHor.php
     *     [1] => ..\estatificador.df06.com.ar\atenderopcion.php
     *     [2] => ..\estatificador.df06.com.ar\config.php
     *     [3] => ..\estatificador.df06.com.ar\consultas.php
     * )
     *
     */

      $pattern = self::addLeadingSlash($pattern);
      $matches = array();
      $folder_group = array(array(self::removeTrailingSlash($path)));

      while($folders = array_shift($folder_group)) {
        //proceso un grupo de folders
        $new_group = array();
        foreach($folders as $folder){
		  $result_glob = glob($folder.$pattern, $flags);
		  if(!$result_glob){
			$result_glob = array();
		  }
          $matches = array_merge($matches, $result_glob);
          if($depth != 0) {
			$result_glob_2 = glob($folder.DIRECTORY_SEPARATOR.'*', GLOB_ONLYDIR);
				if(!$result_glob_2){
					$result_glob_2 = array();
				}
            $new_group = array_merge($new_group, $result_glob_2);
          }
        }
        if($depth != 0) {
          $depth--;
          $folder_group[] = $new_group;
        }

      }

      return str_replace(DIRECTORY_SEPARATOR=='/'?"\\":'/',DIRECTORY_SEPARATOR, $matches);

  }

  
  public static function copy($sourcepath, $file_mask, $destination){
    //echo("FS::copy('".$sourcepath."','".$file_mask."','".$destination."')\n");
    //echo($sourcepath.FS::addLeadingSlash($file_mask)." --> ".FS::removeTrailingSlash($destination).FS::addLeadingSlash($file_mask)."\n");

  /*
   * Ejemplo:
   * FS::copy_to('/home/me/', 'files/downloads/*', '/home/peter');
   *
   * /home/me/files/downloads/readme.txt           =>  /home/peter/files/downloads/readme.txt
   * /home/me/files/downloads/links.html           =>  /home/peter/files/downloads/links.html
   * /home/me/files/downloads/bookmarks/url.html   =>  /home/peter/files/downloads/bookmarks/url.html
   * /home/me/files/downloads/bookmarks/home.html  =>  /home/peter/files/downloads/bookmarks/home.html
   *
   */
  // crea todos los directorios necesarios para poder copiar los archivos en esa ubicacion


    if($sourcepath == "" && file_exists($file_mask)) {
      $files = array($file_mask);
    } else {
      $files = FS::glob($sourcepath, $file_mask, null, -1);
    }
    self::createDir($destination);
    
    $result = true;
    foreach($files as $file){
      $dest_file = FS::removeTrailingSlash($destination) . FS::addLeadingSlash(substr($file, strlen($sourcepath)));
      if(is_dir($file)){
        self::createDir($dest_file);
        $result = true && $result;
      } else {
        if(!is_dir(dirname($dest_file))) self::createDir(dirname($dest_file));
        $result = copy($file, $dest_file) && $result;
      }
    }

    return $result;

  }

  public static function removeTrailingSlash($path){
    /*
     * Remueve la barra final de un path o de un array de paths.
     *
     * Ejemplos:
     *
     *  /     -->  /     no remueve la barra si esta sola
     *  a/b   -->  a/b   no hay bbarra que remover
     *  a/b/  -->  a/b   remueve /
     *  a\b\  -->  a\b   remueve \
     *  /a/   -->  /a    remueve la barra final unicamente
     *  c:/   -->  c:    remueve /
     *  c:\   -->  c:    remueve \
     */
    if(is_array($path)) {
      foreach($path as $k => $p) {
        $path[$k] = self::removeTrailingSlash($p);
      }
      return $path;
    }

    return ($path != "/" && $path != "\\" && (substr($path, -1) == "/" || substr($path, -1) == "\\")) ?
        substr($path, 0, -1) : $path;
  }

  public static function addLeadingSlash($path){
    /*
     * Agrega una barra inicial a un path o a un array de paths.
     * Siempre agrega la indicada en la constante de PHP: "DIRECTORY_SEPARATOR"
     * 
     * Ejemplos:
     *
     *  /     -->  /     no la agrega si ya esta
     *  /a/   -->  /a/   no la agrega si ya esta
     *  \     -->  \     no la agrega si ya esta
     *  \a\   -->  \a\   no la agrega si ya esta
     *  a/b   -->  /a/b  (en Linux agrega /, en Windows agrega \, rigiendose por DIRECTORY_SEPARATOR)
     *  a/b/  -->  /a/b/
     *  a\b\  -->  /a\b\ 
     
     *  c:    -->  c:   interpreta paths de Windows y no los modifica
     *  c:\   -->  c:\  interpreta paths de Windows y no los modifica
     */
    if(is_array($path)) {
      foreach($path as $k => $p) {
        $path[$k] = self::addLeadingSlash($p);
      }
      return $path;
    }

    return ($path != "/" && $path != "\\" && substr($path, 0, 1) != "\\" && substr($path, 0, 1) != "/" && substr($path, 1, 1) != ":") ?
        DIRECTORY_SEPARATOR . $path : $path;
  }

  public static function createDir($dir){
    /*
     * Crea un directorio, creando el arbol completo si hace falta.
     */
    if($dir == dirname($dir)) return true; // porque es el root
    self::createDir(dirname($dir));
    return @mkdir($dir);
  }

  public static function simplifyPath($path, $directory_separator = "/", $equivalent = true){
    $path = trim($path);
    // if it's absolute, it stays absolute:
    $prepend = (substr($path,0,1) == $directory_separator)?$directory_separator:"";
    $path_array = explode($directory_separator, $path);
    if($prepend) array_shift($path_array);
    $output = array();
    foreach($path_array as $val){
      if($val != '..' || ((empty($output) || $last == '..') && $equivalent)) {
        if($val != '' && $val != '.'){
          array_push($output, $val);
          $last = $val;
        }
      } elseif(!empty($output)) {
          array_pop($output);
      }
    }
    return $prepend.implode($directory_separator,$output);
  }

}